//
// Copyright (c) 2007 Tridium, Inc.
// Licensed under the Academic Free License version 3.0
//
// History:
//   28 Mar 07  Brian Frank  Creation
//

#include "sedona.h"

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>



//////////////////////////////////////////////////////////////////////////
// String Formating
//////////////////////////////////////////////////////////////////////////

// shared buffer
static char strbuf[32];
static  uint32_t s_seed = 0;

static int pwm_fd;
#define PWM_IOCTL_STOP			0
#define PWM_IOCTL_SET_FREQ		1


// Str Sys.intStr(int)
Cell sys_Sys_intStr(SedonaVM* vm, Cell* params)
{
  int32_t i = params[0].ival;
  Cell result;

  sprintf(strbuf, "%d", i);

  result.aval = strbuf;
  return result;
}

// Str Sys.hexStr(int)
Cell sys_Sys_hexStr(SedonaVM* vm, Cell* params)
{
  int32_t i = params[0].ival;
  Cell result;

  sprintf(strbuf, "%x", i);

  result.aval = strbuf;
  return result;
}

// Str Sys.longStr(int)
Cell sys_Sys_longStr(SedonaVM* vm, Cell* params)
{
  int64_t i = *(int64_t*)params;
  Cell result;

#ifdef _WIN32
  sprintf(strbuf, "%I64d", i);
#else
  sprintf(strbuf, "%lld", i);
#endif

  result.aval = strbuf;
  return result;
}

// Str Sys.longHexStr(int)
Cell sys_Sys_longHexStr(SedonaVM* vm, Cell* params)
{         
  int64_t i = *(int64_t*)params;  
  Cell result;

#ifdef _WIN32
  sprintf(strbuf, "%I64x", i);
#else
  sprintf(strbuf, "%llx", i);
#endif

  result.aval = strbuf;
  return result;
}

// Str Sys.floatStr(float)
Cell sys_Sys_floatStr(SedonaVM* vm, Cell* params)
{
  float f = params[0].fval;
  Cell result;

  sprintf(strbuf, "%f", f);

  result.aval = strbuf;
  return result;
}

// Str Sys.floatStr(float)
Cell sys_Sys_floatStr2(SedonaVM* vm, Cell* params)
{
  float f = params[0].fval;
  Cell result;

  sprintf(strbuf, "%4.2f", f);

  result.aval = strbuf;
  return result;
}

// Str Sys.floatStr(float)
Cell sys_Sys_floatStr1(SedonaVM* vm, Cell* params)
{
  float f = params[0].fval;
  Cell result;

  sprintf(strbuf, "%3.1f", f);

  result.aval = strbuf;
  return result;
}



// Str Sys.doubleStr(float)
Cell sys_Sys_doubleStr(SedonaVM* vm, Cell* params)
{
  double d = *(double*)params;
  Cell result;      

  sprintf(strbuf, "%lf", d);

  result.aval = strbuf;
  return result;
}

//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////

// int Sys.rand()
Cell sys_Sys_rand(SedonaVM* vm, Cell* params)
{
  Cell result; 
  result.ival = rand();
  return result;
}


Cell sys_Sys_random_seed(SedonaVM* vm, Cell* params)
{
	
	int seed  = params[0].ival;
	
	if(!seed) {
		s_seed = (int)time(NULL);
	} else {
		s_seed = seed;
	}
}
Cell sys_Sys_random_int(SedonaVM* vm, Cell* params)
{
	Cell result;
	int min = params[0].ival;
	int max = params[1].ival;
	
	s_seed=214013*s_seed+2531011;
	
	result.ival = min+(s_seed ^ s_seed>>15)%(max-min+1);
	
	return result;
}

Cell sys_Sys_executeSystemCmd(SedonaVM* vm, Cell* params)
{
	Cell result;
	char * cmd = params[0].aval;

	if (cmd == NULL) {
		printf("### No cmd received!\n");
		return negOneCell;
	}
	printf("The cmd is : %s", cmd);
	result.ival = system(cmd);
	if (result.ival <= 0) {
		printf("system Call failed: %d\n", result.ival);
	}

	return zeroCell;
}

Cell sys_Sys_random_float(SedonaVM* vm, Cell* params)
{
	Cell result;
	float min = params[0].fval;
	float max = params[1].fval;
	
	s_seed=214013*s_seed+2531011;

	result.fval = min+(s_seed>>16)*(1.0f/65535.0f)*(max-min);

	return result;
}

Cell sys_Sys_open_buzzer(SedonaVM* vm, Cell* params)
{	
	pwm_fd = open("/dev/pwm", 0);	
	if (pwm_fd  < 0) {		
		printf("cannt open pwm_buzzer device\n");	
	}	// any function exit call will stop the buzzer	atexit(close_buzzer);

	printf("open pwm_buzzer device\n");
}

Cell sys_Sys_close_buzzer(SedonaVM* vm, Cell* params)
{	
	if (pwm_fd >= 0) 
	{		
		ioctl(pwm_fd, PWM_IOCTL_STOP);	
		close(pwm_fd);		
		pwm_fd = -1;	
	}
}

Cell sys_Sys_set_buzzer_freq(SedonaVM* vm, Cell* params)
{	
	Cell result;
	int freq = params[0].ival;
	printf("setting freq is %d\n", freq);
	
	// this IOCTL command is the key to set frequency
	int ret = ioctl(pwm_fd, PWM_IOCTL_SET_FREQ, freq);
	if(ret < 0) {		
		printf("set the frequency of the buzzer\n");	
	}
}

Cell sys_Sys_RomIntegrityVerify(SedonaVM* vm, Cell* params)
{
	Cell result;

	result.ival = system("tar -tzf /home/AB/BS/rom/kits.tar.gz");
	if (result.ival > 0) {
		system("rm /home/AB/BS/rom/kits.tar.gz");
		system("rm /home/AB/BS/rom/kits_done.txt");
		printf(" ======= > The rom file can not be extracted!\n\n");
	}

	return result;
}



